Skip to content

Add persisted JSON_TABLE PLAN views for dump/restore round-trip tests#67

Draft
NikolayS wants to merge 1 commit into
masterfrom
claude/testplan-jsontable-roundtrip
Draft

Add persisted JSON_TABLE PLAN views for dump/restore round-trip tests#67
NikolayS wants to merge 1 commit into
masterfrom
claude/testplan-jsontable-roundtrip

Conversation

@NikolayS

Copy link
Copy Markdown
Owner

What

Adds a block of persisted (not dropped) views over JSON_TABLE PLAN-clause variants at the end of src/test/regress/sql/sqljson_jsontable.sql, with expected output updated.

Why

Three JSON_TABLE PLAN-clause deparse bugs were recently fixed:

  • 160ef27 — deparse lost the parentheses around a nested parent/child join (PLAN (p0 OUTER (p1 INNER p11)) was emitted as PLAN (p0 OUTER p1 INNER p11)), a dump/restore hazard.
  • cd5fd08 — generated json_table_path_N names could collide with user-supplied path names, silently dropping a sibling path and its columns.
  • af6fad8 — reverted the ON ERROR cascade, restoring per-column ON ERROR/ON EMPTY deparse.

Structural gap: a construct is only truly round-trip tested if it is persisted as a view in the regression database, because pg_upgrade/t/002_pg_upgrade.pl dump-compares every surviving object across a dump/restore + upgrade cycle. The existing JSON_TABLE PLAN views are all dropped before end-of-file, so these fixes had no dump/restore coverage. Every added view is left in place.

Views added

View Construct exercised
jsonb_table_view_pc_plan nested parent/child 2 levels deep, PLAN (p0 OUTER (p1 INNER p11)) — parenthesized child join (160ef27)
jsonb_table_view_sibling_plan sibling paths with explicit CROSS under parent/child OUTER
jsonb_table_view_mixed_plan PLAN (p OUTER ((pb INNER pb1) CROSS (pc OUTER pc1))) — trickiest shape; plus in-test deparse-reparse fixed-point check
jsonb_table_view_default_plan PLAN DEFAULT (INNER, UNION) → normalized explicit PLAN over generated names
jsonb_table_view_name_collision user column/path names matching the json_table_path_N pattern + unnamed paths, verifying no column is silently dropped (cd5fd08)
jsonb_table_view_on_behavior per-column + table-level ON ERROR/ON EMPTY; explicit column behavior preserved, table-level ERROR ON ERROR does not cascade (af6fad8)

Each view pins its pg_get_viewdef() output and runs a SELECT that checks the resulting rows (e.g. jsonb_table_view_name_collision returns all three columns' rows — the cd5fd08 failure mode would drop one).

The jsonb_table_view_mixed_plan block also proves round-trip stability inside the test itself: it recreates a second view from the first view's exact pg_get_viewdef() output (via \gexec) and asserts the two definitions are byte-for-byte identical (deparse_roundtrip_stable = t).

Test evidence

  • sqljson_jsontable regression test: passing (ok 1 - sqljson_jsontable, All 1 tests passed).
  • The deparse-reparse fixed-point check returns t.
  • Manually confirmed the deparsed plans keep their parentheses, the collision view keeps all columns, and generated names skip user-supplied json_table_path_1.

Test-only change; no backend code is modified.

Closes #61

🤖 Generated with Claude Code

https://claude.ai/code/session_01PtxA6B4d47ietk5dGsseuP


Generated by Claude Code

The JSON_TABLE regression tests exercised the tricky PLAN-clause deparse
paths (nested parent/child joins, sibling UNION/CROSS joins, PLAN DEFAULT,
generated-vs-user path name collisions, per-column and table-level ON
ERROR/ON EMPTY) only through views that are dropped before the end of the
file, or through bare SELECTs.  A construct is only truly round-trip tested
if it is persisted as a view in the regression database, because
pg_upgrade's 002_pg_upgrade.pl dump-compares every surviving object across a
dump/restore and upgrade cycle.  None of the JSON_TABLE PLAN views survived,
so the recent deparse fixes had no dump/restore coverage.

Add a block of views at the end of sqljson_jsontable.sql that are left in
place, each covering a distinct PLAN construct:

  - jsonb_table_view_pc_plan: nested parent/child two levels deep with an
    explicit parenthesized child join, PLAN (p0 OUTER (p1 INNER p11)); the
    parentheses must survive deparsing or the plan reparses to a different
    tree.
  - jsonb_table_view_sibling_plan: sibling paths joined with explicit CROSS
    under a parent/child OUTER join.
  - jsonb_table_view_mixed_plan: the trickiest shape,
    PLAN (p OUTER ((pb INNER pb1) CROSS (pc OUTER pc1))), plus a
    deparse-reparse fixed-point check that recreates the view from its own
    pg_get_viewdef() output and asserts the two definitions are identical.
  - jsonb_table_view_default_plan: PLAN DEFAULT (INNER, UNION), which
    normalizes to an explicit PLAN over generated path names.
  - jsonb_table_view_name_collision: user column/path names deliberately
    matching the generated json_table_path_N pattern mixed with unnamed
    paths, verifying no column is silently dropped.
  - jsonb_table_view_on_behavior: per-column and table-level ON ERROR/ON
    EMPTY, verifying a column's explicit behavior is preserved and the
    table-level ERROR ON ERROR does not cascade.

Each view pins its pg_get_viewdef() output and runs a SELECT that checks the
resulting rows, so a regression that drops a column or mangles a plan is
caught both here and by the pg_upgrade dump comparison.

Co-Authored-By: Claude Fable 5 <[email protected]>
Claude-Session: https://claude.ai/code/session_01PtxA6B4d47ietk5dGsseuP
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Persist JSON_TABLE PLAN variants as views for round-trip coverage

2 participants